#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <time.h> // 新增头文件，用于高精度计时

#include "lcd.h"
#include "ts.h"
#include "mp3.h"
#include "HZK16.h" // 中文字体
#include <linux/time.h>

// 1. 定义程序状态
enum State {
    IDLE,      // 空闲/正常弹奏模式
    RECORDING, // 录制模式
    PLAYBACK   // 回放模式
};

// 2. 定义音符事件结构体
#define MAX_NOTES 500 // 最多可以录制500个音符
struct NoteEvent {
    int key_index;
    long delay_us; // 距离上一个事件的延迟（微秒）
};

// 3. 定义全局变量
enum State current_state = IDLE;       // 当前程序状态
struct NoteEvent recorded_song[MAX_NOTES]; // 存储录制的歌曲
int note_count = 0;                    // 已录制的音符数量
struct timespec last_event_time;       // 上一个事件的时间戳

// 4. 定义UI按钮的触摸区域
#define BTN_WIDTH 100
#define BTN_HEIGHT 40
#define BTN_Y 430

#define REC_BTN_X 150
#define STOP_BTN_X 350
#define PLAY_BTN_X 550

// 绘制UI按钮的函数
void draw_ui_buttons()
{
    // 绘制背景矩形
    lcd_draw_rect(REC_BTN_X, BTN_Y, BTN_WIDTH, BTN_HEIGHT, 0x808080);  // 灰色
    lcd_draw_rect(STOP_BTN_X, BTN_Y, BTN_WIDTH, BTN_HEIGHT, 0x808080); // 灰色
    lcd_draw_rect(PLAY_BTN_X, BTN_Y, BTN_WIDTH, BTN_HEIGHT, 0x808080); // 灰色

    // 绘制按钮文字（使用HZK16中文字体）
    // "录制" - GBK: C2 BC D6 C6
    draw_16x16(REC_BTN_X + 18, BTN_Y + 12, &szHZK16[32*( (0xC2-0xA1)*94 + (0xBC-0xA1) )], 0xFFFFFF);
    draw_16x16(REC_BTN_X + 18 + 16, BTN_Y + 12, &szHZK16[32*( (0xD6-0xA1)*94 + (0xC6-0xA1) )], 0xFFFFFF);

    // "停止" - GBK: CD A3 D6 B9
    draw_16x16(STOP_BTN_X + 18, BTN_Y + 12, &szHZK16[32*( (0xCD-0xA1)*94 + (0xA3-0xA1) )], 0xFFFFFF);
    draw_16x16(STOP_BTN_X + 18 + 16, BTN_Y + 12, &szHZK16[32*( (0xD6-0xA1)*94 + (0xB9-0xA1) )], 0xFFFFFF);

    // "播放" - GBK: B2 A5 B7 C5
    draw_16x16(PLAY_BTN_X + 18, BTN_Y + 12, &szHZK16[32*( (0xB2-0xA1)*94 + (0xA5-0xA1) )], 0xFFFFFF);
    draw_16x16(PLAY_BTN_X + 18 + 16, BTN_Y + 12, &szHZK16[32*( (0xB7-0xA1)*94 + (0xC5-0xA1) )], 0xFFFFFF);
}

// 歌曲回放函数
void playback_song()
{
    printf("Starting playback of %d notes...\n", note_count);
    for (int i = 0; i < note_count; i++) {
        // 等待记录的时间间隔
        usleep(recorded_song[i].delay_us);

        int key_index = recorded_song[i].key_index;

        // 模拟按键按下
        draw_bmp("./res/imagefiles/key_press.bmp", 2 + key_index * (64 + 2), 47);
        play_mp3(key_index);

        printf("Playing note: key=%d\n", key_index);

        // 保持按下的视觉效果一小段时间
        usleep(150000);

        // 模拟按键释放
        draw_bmp("./res/imagefiles/key_release.bmp", 2 + key_index * (64 + 2), 47);
    }
    printf("Playback finished.\n");
}


int main()
{
    struct postion pos;
    int i;
    
    int fd = open("/dev/ubuntu_lcd",O_RDWR);
    if(fd==-1)
    {
        printf("opened error!");
        return -1;
    }
    
    plcd = mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(plcd == MAP_FAILED)
    {
        perror("mmap");
        close(fd);
        return -1;
    }

    // 初始化界面
    draw_bmp("./res/imagefiles/bg.bmp",0,0);
    for(i=0; i<12; i++)
    {
        draw_bmp("./res/imagefiles/key_release.bmp", 2+i*(64+2), 47);
    }
    draw_bmp("./res/imagefiles/title.bmp",0,0);
    
    // 绘制新增的控制按钮
    draw_ui_buttons();
    
    while(1)
    {
        // 在回放模式下，不响应任何触摸
        if (current_state == PLAYBACK) {
            playback_song();
            current_state = IDLE; // 回放结束后，返回空闲状态
            continue; // 继续下一次循环
        }

        pos = ts_xy();
        
        // --- 触摸判断逻辑 ---

        // 1. 判断是否点击 "录制" 按钮
        if (pos.x > REC_BTN_X && pos.x < REC_BTN_X + BTN_WIDTH &&
            pos.y > BTN_Y && pos.y < BTN_Y + BTN_HEIGHT)
        {
            if (current_state == IDLE) {
                current_state = RECORDING;
                note_count = 0; // 重置音符计数器
                clock_gettime(CLOCK_MONOTONIC, &last_event_time); // 获取起始时间
                printf("Start recording...\n");
                lcd_draw_rect(REC_BTN_X, BTN_Y, BTN_WIDTH, BTN_HEIGHT, 0xFF0000); // 按钮变红，提示正在录制
                draw_16x16(REC_BTN_X + 18, BTN_Y + 12, &szHZK16[32*( (0xC2-0xA1)*94 + (0xBC-0xA1) )], 0xFFFFFF);
                draw_16x16(REC_BTN_X + 18 + 16, BTN_Y + 12, &szHZK16[32*( (0xD6-0xA1)*94 + (0xC6-0xA1) )], 0xFFFFFF);

            }
        }
        // 2. 判断是否点击 "停止" 按钮
        else if (pos.x > STOP_BTN_X && pos.x < STOP_BTN_X + BTN_WIDTH &&
                 pos.y > BTN_Y && pos.y < BTN_Y + BTN_HEIGHT)
        {
            if (current_state == RECORDING) {
                current_state = IDLE;
                printf("Stop recording. Total notes: %d\n", note_count);
                // 恢复录制按钮颜色
                lcd_draw_rect(REC_BTN_X, BTN_Y, BTN_WIDTH, BTN_HEIGHT, 0x808080);
                draw_16x16(REC_BTN_X + 18, BTN_Y + 12, &szHZK16[32*( (0xC2-0xA1)*94 + (0xBC-0xA1) )], 0xFFFFFF);
                draw_16x16(REC_BTN_X + 18 + 16, BTN_Y + 12, &szHZK16[32*( (0xD6-0xA1)*94 + (0xC6-0xA1) )], 0xFFFFFF);

            }
        }
        // 3. 判断是否点击 "播放" 按钮
        else if (pos.x > PLAY_BTN_X && pos.x < PLAY_BTN_X + BTN_WIDTH &&
                 pos.y > BTN_Y && pos.y < BTN_Y + BTN_HEIGHT)
        {
            if (current_state == IDLE && note_count > 0) {
                current_state = PLAYBACK; // 进入回放模式，循环的下一次迭代将执行回放
            }
        }
        // 4. 判断是否点击钢琴按键区域
        else if (pos.y >= 47 && pos.y <= 327) 
        {
            int key_index = pos.x / (64 + 2);
            if (key_index >= 0 && key_index < 12) 
            {
                // 如果正在录制，则记录音符事件
                if (current_state == RECORDING && note_count < MAX_NOTES) {
                    struct timespec current_time;
                    clock_gettime(CLOCK_MONOTONIC, &current_time);

                    // 计算与上一个事件的时间差（微秒）
                    long delay_ns = (current_time.tv_sec - last_event_time.tv_sec) * 1000000000L + 
                                    (current_time.tv_nsec - last_event_time.tv_nsec);
                    
                    recorded_song[note_count].key_index = key_index;
                    recorded_song[note_count].delay_us = delay_ns / 1000;
                    note_count++;

                    last_event_time = current_time; // 更新上一个事件的时间戳
                }

                // 正常响应按键（显示、发声）
                draw_bmp("./res/imagefiles/key_press.bmp", 2 + key_index * (64 + 2), 47);
                play_mp3(key_index);
                printf("Touch position: x=%d, y=%d, key=%d\n", pos.x, pos.y, key_index);
                usleep(100000);
                draw_bmp("./res/imagefiles/key_release.bmp", 2 + key_index * (64 + 2), 47);
            }
        } 

        usleep(20000); // 适当延时，避免过高 CPU 使用率
    }

    // 程序退出前的清理工作
    munmap(plcd, 800*480*4);
    close(fd);

    return 0;
}